home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dskut / bteasy14.zip / BOOTINST.C < prev    next >
C/C++ Source or Header  |  1993-09-11  |  8KB  |  256 lines

  1. /*
  2.  * Boot installator.
  3.  * Author: Serge Vakulenko, <vak@kiae.su>
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <fcntl.h>
  8. #include <dos.h>
  9.  
  10. #define BOOTFILE    "boot.bin"
  11. #define SAVEFILE    "bootsav.bin"
  12. #define SAVE2FILE    "boot2sav.bin"
  13.  
  14. #define PartAddr        0x1be    /* Offset to partition table */
  15. #define ValidationAddr  0x1fe    /* Offset to validation bytes */
  16. #define MAGIC        0xaa55    /* Validation tag */
  17.  
  18. #define DISK1        0
  19. #define DISK2        1
  20. #define READ        0
  21. #define WRITE        1
  22.  
  23. typedef struct PartitionEntry {
  24.     unsigned char    bootIndicator;
  25.     unsigned char    beginHead;
  26.     unsigned char    beginSector;
  27.     unsigned char    beginCyl;
  28.     unsigned char    systemId;
  29.     unsigned char    endHead;
  30.     unsigned char    endSector;
  31.     unsigned char    endCyl;
  32.     unsigned short    relSectorLow;
  33.     unsigned short    relSectorHigh;
  34.     unsigned short    numSectorsLow;
  35.     unsigned short    numSectorsHigh;
  36. } PartitionEntry;
  37.  
  38. unsigned char bootRecord [512];
  39. unsigned char bootProg [512];
  40.  
  41. yes ()
  42. {
  43.     char reply [80];
  44.  
  45.     printf (" (yes/no) ");
  46.     fgets (reply, sizeof (reply), stdin);
  47.     return (!stricmp (reply, "y\n") || !stricmp (reply, "yes\n"));
  48. }
  49.  
  50. main (argc, argv)
  51. char **argv;
  52. {
  53.     char *bootfile;
  54.     int disk2present;
  55.  
  56.     printf ("Boot installer, version 1.4, Copyright (C) Serge Vakulenko\n\n");
  57.  
  58.     printf ("This utility allows you to install new boot program on your\n");
  59.     printf ("hard disk.  The usage is:\n\n");
  60.     printf ("        bootinst [bootfile]\n\n");
  61.     printf ("It installs boot block from bootfile (default boot.bin) to the first\n");
  62.     printf ("drive and, if second drive is present, to the second drive.\n");
  63.     printf ("Old boot sectors are saved to bootsav.bin and boot2sav.bin respectively.\n");
  64.     printf ("\nYou can copy and distribute this software free of charge,\n");
  65.     printf ("provided that sources are included.  No warranty, of course.\n\n");
  66.  
  67.     if (argc > 3)
  68.         return (-1);
  69.  
  70.     bootfile = argc>1 ? argv[1] : BOOTFILE;
  71.     if (access (bootfile, 4) < 0) {
  72.         perror (bootfile);
  73.         return (-1);
  74.     }
  75.  
  76.     /*
  77.      * Is second disk present?  Try to read boot sector,
  78.      * check that it is bootable and has valid partition table.
  79.      */
  80.     disk2present = (bootio (DISK2, READ, 0, 0, 1, bootRecord) == 0 &&
  81.         *(short *) &bootRecord [ValidationAddr] == (short) MAGIC &&
  82.         (bootRecord [PartAddr] == 0 || bootRecord [PartAddr] == 0x80) &&
  83.         (bootRecord [PartAddr+16] == 0 || bootRecord [PartAddr+16] == 0x80) &&
  84.         (bootRecord [PartAddr+32] == 0 || bootRecord [PartAddr+32] == 0x80) &&
  85.         (bootRecord [PartAddr+48] == 0 || bootRecord [PartAddr+48] == 0x80));
  86.  
  87.     printf ("Continue with installation?");
  88.     if (! yes ())
  89.         return (0);
  90.  
  91.     install (DISK1, bootfile, SAVEFILE);
  92.  
  93.     if (disk2present)
  94.         install (DISK2, bootfile, SAVE2FILE);
  95.  
  96.     return (0);
  97. }
  98.  
  99. install (disk, file, savefile)
  100. char *file, *savefile;
  101. {
  102.     int rc, fd;
  103.  
  104.     rc = bootio (disk, READ, 0, 0, 1, bootRecord);
  105.     if (rc) {
  106.         fprintf (stderr, "Error %d reading boot record from disk %d\n",
  107.             rc, disk);
  108.         exit (-1);
  109.     }
  110.     if (*(short *) &bootRecord [ValidationAddr] != (short) MAGIC) {
  111.         fprintf (stderr, "Bad master boot record on disk %d!\n",
  112.             disk);
  113.         exit (-1);
  114.     }
  115.  
  116.     printtable (disk);
  117.  
  118.     fd = open (file, O_RDONLY|O_BINARY);
  119.     if (fd < 0) {
  120.         fprintf (stderr, "Cannot read file %s\n", file);
  121.         exit (-1);
  122.     }
  123.     if (read (fd, bootProg, 512) != 512) {
  124.         fprintf (stderr, "Error reading %s\n", file);
  125.         exit (-1);
  126.     }
  127.     close (fd);
  128.     if (*(short *) &bootProg [ValidationAddr] != (short) MAGIC) {
  129.         fprintf (stderr, "Bad boot image in file %s\n", file);
  130.         exit (-1);
  131.     }
  132.  
  133.     printf ("\nAre you sure you want to install new boot on disk %d?",
  134.         disk);
  135.     if (! yes ())
  136.         exit (0);
  137.  
  138.     close (creat (savefile, 0664));
  139.     fd = open (savefile, O_WRONLY|O_BINARY);
  140.     if (fd < 0) {
  141.         fprintf (stderr, "Cannot write to file %s\n", savefile);
  142.         exit (-1);
  143.     }
  144.     if (write (fd, bootRecord, 512) != 512) {
  145.         fprintf (stderr, "Error writing to %s\n", savefile);
  146.         exit (-1);
  147.     }
  148.     close (fd);
  149.  
  150.     memcpy (bootRecord, bootProg, PartAddr);
  151.  
  152.     rc = bootio (disk, WRITE, 0, 0, 1, bootRecord);
  153.     if (rc) {
  154.         fprintf (stderr, "Error %d updating boot record on disk %d\n",
  155.             rc, disk);
  156.         exit (-1);
  157.     }
  158.     printf ("New boot record successfully installed.\n");
  159. }
  160.  
  161. bootio (disk, op, head, cyl, sect, buf)
  162. char *buf;
  163. {
  164.     return (biosdisk (op==WRITE ? 3 : 2, disk==DISK1 ? 0x80 : 0x81,
  165.         head, cyl, sect, 1, buf));
  166. }
  167.  
  168. static char head1 [] =    "┌─┬─────────┬────┬────┬───────────────┬───────────────┬─────────┬─────────┐\n";
  169. static char head2 [] =    "│ │Partition│Can │Boot│   Beginning   │    Ending     │ Relative│Number of│\n";
  170. static char head3 [] =    "│N│  Type   │Boot│Part│Head  Cyl  Sect│Head  Cyl  Sect│ Sectors │ Sectors │\n";
  171. static char head4 [] =    "├─┼─────────┼────┼────┼────┬─────┬────┼────┬─────┬────┼─────────┼─────────┤\n";
  172. static char mid1 [] =    "│%d│%-9.9s│%-4.4s│%-4.4s│%3u │%4u │%3u │%3u │%4u │%3u │%8lu │%8lu │\n";
  173. static char mid2 [] =    "├─┼─────────┼────┼────┼────┼─────┼────┼────┼─────┼────┼─────────┼─────────┤\n";
  174. static char foot [] =    "└─┴─────────┴────┴────┴────┴─────┴────┴────┴─────┴────┴─────────┴─────────┘\n";
  175.  
  176. printtable (disk)
  177. {
  178.     PartitionEntry *part = (PartitionEntry *) (bootRecord + PartAddr);
  179.     int i, cb;
  180.     long relSectors;
  181.     long numSectors;
  182.     char *typeString, block [512];
  183.  
  184.     printf ("\n");
  185.     printf (head1);
  186.     printf (head2);
  187.     printf (head3);
  188.     printf (head4);
  189.  
  190.     for (i=0; i<4; ++i) {
  191.         switch (part->systemId) {
  192.         default:    typeString = "  ?????";   cb = 1; break;
  193.         case 0:        typeString = "  empty";   cb = 0; break;
  194.         case 1:        typeString = "  dos-12";  cb = 1; break;
  195.         case 2:        typeString = "  xenix";   cb = 1; break;
  196.         case 3:        typeString = "xenix usr"; cb = 0; break;
  197.         case 4:        typeString = "  dos-16";  cb = 1; break;
  198.         case 5:        typeString = "  extend";  cb = 0; break;
  199.         case 6:        typeString = "  bigdos";  cb = 1; break;
  200.         case 7:        typeString = "  hpfs";    cb = 1; break;
  201.         case 0x75:    typeString = "  pcix";    cb = 1; break;
  202.         case 0xdb:    typeString = "  cp/m";    cb = 1; break;
  203.         case 0xff:    typeString = "  bbt";     cb = 0; break;
  204.         case 0x08:    typeString = "  aix";     cb = 0; break;
  205.         case 0x09:    typeString = " coherent"; cb = 1; break;
  206.         case 0x0A:    typeString = "  os/2";    cb = 1; break;
  207.         case 0x10:    typeString = "  opus";    cb = 1; break;
  208.         case 0x40:    typeString = "venix 286"; cb = 1; break;
  209.         case 0x50:
  210.         case 0x51:    typeString = "  dm";      cb = 1; break;
  211.         case 0x52:    typeString = "microport"; cb = 1; break;
  212.         case 0x56:    typeString = "  gb";      cb = 1; break;
  213.         case 0x61:
  214.         case 0xE1:
  215.         case 0xE3:
  216.         case 0xE4:
  217.         case 0xF1:
  218.         case 0xF4:    typeString = "  speed";   cb = 1; break;
  219.         case 0x63:    typeString = "  unix";    cb = 1; break;
  220.         case 0x64:    typeString = "novell286"; cb = 1; break;
  221.         case 0x65:    typeString = "novell386"; cb = 1; break;
  222.         case 0x80:    typeString = "old minix"; cb = 1; break;
  223.         case 0x81:    typeString = "  minix";   cb = 1; break;
  224.         case 0x82:    typeString = "  linux";   cb = 1; break;
  225.         case 0x93:    typeString = "  amoeba";  cb = 1; break;
  226.         case 0x94:    typeString = "amoebaBBT"; cb = 0; break;
  227.         case 0xA5:    typeString = "  386bsd";  cb = 1; break;
  228.         case 0x9f:
  229.         case 0xB7:    typeString = "  bsdi";    cb = 1; break;
  230.         case 0xB8:    typeString = "bsdi swap"; cb = 0; break;
  231.         case 0xF2:    typeString = " dos sec";  cb = 1; break;
  232.         }
  233.         relSectors = part->relSectorLow |
  234.             (unsigned long) part->relSectorHigh<<16;
  235.         numSectors = part->numSectorsLow |
  236.             (unsigned long) part->numSectorsHigh<<16;
  237.  
  238.         if (cb && (bootio (disk, READ, part->beginHead, part->beginCyl,
  239.             part->beginSector, block) != 0 ||
  240.             *(short *) &block [ValidationAddr] != (short) MAGIC))
  241.             cb = 0;
  242.  
  243.         printf (mid1, i+1, typeString, cb ? " yes" : " no",
  244.             (part->bootIndicator & 0x80) ? " yes" : " no",
  245.             part->beginHead, part->beginCyl |
  246.             part->beginSector<<2 & 0x300,
  247.             part->beginSector & 077, part->endHead,
  248.             part->endCyl | part->endSector<<2 & 0x300,
  249.             part->endSector & 077, relSectors, numSectors);
  250.         if (i < 3)
  251.             printf (mid2);
  252.         ++part;
  253.     }
  254.     printf (foot);
  255. }
  256.